package com.lottery.service.pc28.accoutService.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lottery.dao.pc28.accoutDao.CustomerServiceDao;
import com.lottery.dao.pc28.accoutDao.ManualCustomerDao;
import com.lottery.dao.pc28.accoutDao.UserDao;
import com.lottery.dao.pc28.bettingDao.BettingLimitationDao;
import com.lottery.dao.pc28.lobbyDao.BettinginfoDao;
import com.lottery.dao.pc28.lobbyDao.NoticeDao;
import com.lottery.dao.pc28.statisticsDao.AgencyDao;
import com.lottery.dao.pc28.wealthDao.AccountDao;
import com.lottery.dao.pc28.wealthDao.AccountTransactionDao;
import com.lottery.dto.AccountTransactionDto;
import com.lottery.dto.UtilsDto;
import com.lottery.entity.*;
import com.lottery.service.pc28.JedisClient;
import com.lottery.service.pc28.accoutService.ManualCustomerservice;
import com.lottery.service.pc28.wealthService.WithdrawalsService;
import com.lottery.utils.CustomerContext;
import com.lottery.utils.DateUtil;
import com.lottery.utils.RandCodeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class ManualCustomerServiceimpl implements ManualCustomerservice {

	@Autowired
	private ManualCustomerDao manualcustomerDao;

	@Autowired
	private BettinginfoDao bettinginfoDao;

	// @Autowired
	private CustomerContext customerContext;

	@Autowired
	private JedisClient jedisClient;

	@Autowired
	private UserDao userdao;

	@Autowired
	private AgencyDao agencydao;

	@Autowired
	private AccountDao accountdao;

	@Autowired
	private CustomerServiceDao customerdao;

	@Autowired
	private NoticeDao noticeDao;

	@Autowired
	private AccountTransactionDao accounttransactionDao;

	@Autowired
	private BettingLimitationDao bettinglimitationDao;

	@Resource
	public WithdrawalsService withdrawalsService;

	public static Map<Integer, Integer> onlineMap = new ConcurrentHashMap<Integer, Integer>();

	// #生成的手机短信验证码以 key的 形式存储
	@Value("${LOGINSYSTEM1}")
	private String LOGINSYSTEM1;

	@Value("${AUTOCASH}")
	private String AUTOCASH;

	@Value("${LIMITAUTOCASH}")
	private String LIMITAUTOCASH;

	@Value("${HOSTADDR}")
	private String HOSTADDR;

	@Autowired
	private AccountTransactionDao accounttransactiondao;

	// 日志
	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	// 客户发送消息
	@Override
	public String userSendMsg(int srcId, int dstId, String message) {
		// 日志
		logger.info("userSendMsg in:{},{},{}", srcId, dstId, message);

		Map<String, Object> maxmap = new HashMap<String, Object>();
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		try {
			// 先发送者会发送消息给接受者通过接受者的 id插入到表中
			ManualCustomer mcs = new ManualCustomer();
			mcs.setScrId(srcId);
			mcs.setDstId(dstId);
			mcs.setMsg(message);
			// Date date = new Date();
			// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd
			// HH:mm:ss");
			// String dataNow = sdf.format(date);
			String dataNow = DateUtil.getFormatDate("yyyy-MM-dd HH:mm:ss");
			mcs.setSendTime(dataNow);
			mcs.setPull("0");
			manualcustomerDao.insertManualCustomer(mcs);
			// 日志
			logger.info("userSendMsg mcs信息:{}", mcs);
			customerContext = CustomerContext.getInstance();
			if (!customerContext.userSendMsg(srcId, dstId, mcs.getId(), message, dataNow)) {
				maxmap.put("result", "1");
				maxmap.put("ErrMsg", "发送失败");
				logger.error("{} user send to {} fail....", srcId, dstId);
				return JSON.toJSONString(maxmap, true);
			}
			// 查询表的属性
			ArrayList<CommunionMsg> arraylist = customerContext.userPullMsg(srcId);
			// Arraymsg数组中的
			if (arraylist != null) {
				for (CommunionMsg one : arraylist) {
					Map<String, Object> map = new HashMap<String, Object>();
					map.put("msgid", one.getMsgid());
					map.put("from_id", one.getScrId());
					map.put("to_id", srcId);
					map.put("message", one.getMsg());
					map.put("msgTime", one.getSendTime());
					list.add(map);
				}
				// 发送成功，返回状态0,条数和Arraymsg数组
			}
			maxmap.put("msg_count", arraylist == null ? 0 : arraylist.size());
			maxmap.put("Arraymsg", list);
			maxmap.put("result", "0");
			// 日志
			logger.info("userSendMsg maxmap:{}", maxmap);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("userSendMsg error:", e);
			// 发送给失败，返回 状态 1，失败原因
			maxmap.put("result", "1");
			maxmap.put("msg", "发送失败");
		}

		// 转成JsontoString
		String json = JSON.toJSONString(maxmap, true);
		// JSONObject jsonmaxmap = JSONObject.parseObject(maxmap.toString());
		// 日志
		logger.info("userSendMsg out json:{}", json);
		return json;
	}

	/**
	 * 客服发送 消息
	 */
	@Override
	public String serverSendMsg(int srcId, int dstId, String message) {
		// 日志
		logger.info("serverSendMsg in:{},{},{}", srcId, dstId, message);
		// 查询表的属性
		Map<String, Object> maxmap = new HashMap<String, Object>();
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		try {
			// 先发送者会发送消息给接受者通过接受者的 id插入到表中
			ManualCustomer mcs = new ManualCustomer();
			mcs.setScrId(srcId);
			mcs.setDstId(dstId);
			mcs.setMsg(message);
			// Date date = new Date();
			// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd
			// HH:mm:ss");
			// String dataNow = sdf.format(date);
			String dataNow = DateUtil.getFormatDate("yyyy-MM-dd HH:mm:ss");
			mcs.setSendTime(dataNow);
			mcs.setPull("0");
			manualcustomerDao.insertManualCustomer(mcs);
			// 日志
			logger.info("serverSendMsg mcs信息:{}", mcs);
			customerContext = CustomerContext.getInstance();
			if (!customerContext.serverSendMsg(srcId, dstId, mcs.getId(), message, dataNow)) {
				maxmap.put("result", "1");
				maxmap.put("ErrMsg", "发送失败");
				logger.error("{} server send to {} fail....", srcId, dstId);
				return JSON.toJSONString(maxmap, true);
			}
			customerContext = CustomerContext.getInstance();
			ArrayList<CommunionMsg> clientsMsg = customerContext.serverPullMsg(srcId, dstId);
			for (CommunionMsg one : clientsMsg) {
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("msgId", one.getMsgid());
				map.put("message", one.getMsg());
				map.put("msgTime", one.getSendTime());
				list.add(map);
			}

		} catch (Exception e) {
			e.printStackTrace();
			logger.error("serverSendMsg error:", e);
			// 发送给失败，返回 状态 1，失败原因
			maxmap.put("result", "1");
			maxmap.put("ErrMsg", "发送失败");
		}
		// 发送成功，返回状态0,条数和Arraymsg数组
		maxmap.put("result", "0");
		maxmap.put("msgArray", list);

		// 转成JsontoString
		String json = JSON.toJSONString(maxmap, true);
		// 日志
		logger.info("serverSendMsg out json:{}", json);
		return json;
	}

	// 用户接受消息
	@Override
	public String clientGetMsg(int userId) {
		// user_id可能 是用户id，也可能是客服 id
		// 日志
		logger.info("clientGetMsg in:{}", userId);
		Map<String, Object> maxmap = new HashMap<String, Object>();
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		try {
			// 先，接受者接受发送者发送的消息，通过接受者的id
			customerContext = CustomerContext.getInstance();
			ArrayList<CommunionMsg> arraylist = customerContext.userPullMsg(userId);

			if (arraylist != null) {
				// Arraymsg数组中的
				for (CommunionMsg one : arraylist) {
					Map<String, Object> map = new HashMap<String, Object>();
					map.put("msgid", one.getMsgid());
					map.put("from_id", one.getScrId());
					map.put("to_id", userId);
					map.put("message", one.getMsg());
					map.put("msgTime", one.getSendTime());
					list.add(map);
				}
			}

			// 接受成功后返回状态0，条数和Arraylist数组
			maxmap.put("result", "0");
			maxmap.put("msg_count", arraylist == null ? 0 : arraylist.size());
			maxmap.put("Arraymsg", list);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("clientGetMsg error:", e);
			// 接受失败返回状态 1，失败原因
			maxmap.put("result", "1");
			maxmap.put("ErrMsg", "接受失败 ");
		}
		// 转成JsontoString
		String json = JSON.toJSONString(maxmap, true);

		// 日志
		logger.info("clientGetMsg out json:{}", json);
		return json;
	}

	/**
	 * 客服接受消息
	 */
	@Override
	public String serverGetMsg(int serverId, int userId) {
		// user_id可能 是用户id，也可能是客服 id
		// 日志
		logger.info("serverGetMsg in:{}--{}", serverId, userId);
		Map<String, Object> maxmap = new HashMap<String, Object>();
		try {
			List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
			customerContext = CustomerContext.getInstance();
			if (0 != userId) {
				ArrayList<CommunionMsg> clientsMsg = customerContext.serverPullMsg(serverId, userId);
				for (CommunionMsg one : clientsMsg) {
					Map<String, Object> map = new HashMap<String, Object>();
					map.put("msgId", one.getMsgid());
					map.put("message", one.getMsg());
					map.put("msgTime", one.getSendTime());
					list.add(map);
				}
			} else { // 自动分配客户消息
				ArrayList<CommunionMsg> serverSystemMsg = customerContext.getServerSystemMsg(serverId);
				if (serverSystemMsg != null) {
					for (CommunionMsg one : serverSystemMsg) {
						Map<String, Object> map = new HashMap<String, Object>();
						User userinfo = userdao.selectId(one.getScrId());
						map.put("msgId", one.getMsgid());
						map.put("message", one.getMsg());
						map.put("clientId", one.getScrId());
						map.put("msgTime", one.getSendTime());
						map.put("userName", userinfo.getUserName());
						map.put("headPic", userinfo.getHeadPic());
						list.add(map);
					}
				}
			}

			// 接受成功后返回状态0，条数和Arraylist数组
			maxmap.put("result", "0");
			maxmap.put("msgArray", list);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("serverGetMsg error:", e);
			// 接受失败返回状态 1，失败原因
			maxmap.put("result", "1");
			maxmap.put("ErrMsg", "接受失败 ");
		}
		// 转成JsontoString
		String json = JSON.toJSONString(maxmap, true);

		// 日志
		logger.info("serverGetMsg out json:{}", json);
		return json;
	}

	/**
	 * 客服拉取最近30分钟消息
	 */
	@Override
	public String serverGetLastMsg(int serverId) {
		// 日志
		logger.info("serverGetLastMsg in:{}", serverId);

		Map<String, Object> maxmap = new HashMap<String, Object>();
		try {
			List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
			// 获取
			customerContext = CustomerContext.getInstance();
			for (Entry<Integer, ArrayList<CommunionMsg>> clientMsgMap : customerContext.getServersMap().get(serverId)
					.getMessageList().entrySet()) {

				int clientId = clientMsgMap.getKey();
				User user = userdao.selectId(clientId);
				ArrayList<CommunionMsg> msgs = clientMsgMap.getValue();

				// Arraymsg数组中的
				List<Map<String, Object>> list1 = new ArrayList<Map<String, Object>>();
				for (CommunionMsg msg : msgs) {
					Map<String, Object> map1 = new HashMap<String, Object>();
					map1.put("msgId", msg.getMsgid());
					map1.put("srcId", msg.getScrId());
					map1.put("dstId", msg.getDstId());
					map1.put("msgTime", msg.getSendTime());
					map1.put("msg", msg.getMsg());
					list1.add(map1);
				}
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("clientId", clientId);
				map.put("clientName", user.getUserName());
				map.put("headPic", user.getHeadPic());
				map.put("msgArray", list1);
				list.add(map);
			}
			maxmap.put("clientArray", list);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("serverGetLastMsg error:", e);
			// 接受失败返回状态 1，失败原因
			maxmap.put("result", "1");
			maxmap.put("ErrMsg", "获取失败 ");
		}
		maxmap.put("result", "0");

		// 转成JsontoString
		String json = JSON.toJSONString(maxmap, true);
		// 日志
		logger.info("serverGetLastMsg out json:{}", json);
		return json;
	}

	/**
	 * 客服拉取历史消息
	 */
	@Override
	public String serverGetHistoryMsg(int serverId, int userId, int pageNum, int pageSize, int minMsgId) {
		// 日志
		logger.info("serverGetHistoryMsg in:serverId{},userId{},pageNum{},pageSize{},minMsgId{}", serverId, userId,
				pageNum, pageSize, minMsgId);
		Map<String, Object> maxmap = new HashMap<String, Object>();
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();

		try {

			int skip = (pageNum - 1) * pageSize;
			Map<String, Integer> params = new HashMap<String, Integer>();
			params.put("serverId", serverId);
			params.put("skip", skip);
			params.put("pageSize", pageSize);
			// params.put("minMsgId", minMsgId);
			// 先客服 会根据自身的id和客户的id进行对数据库中查询，有则拉取回来
			ArrayList<ManualCustomer> msgs;
			if (userId != 0) {
				params.put("userId", userId);
				msgs = manualcustomerDao.SelectServerMsg(params);
			} else {
				msgs = manualcustomerDao.SelectServerMsg1(params);
			}

			// 日志
			logger.info("selectByDstId信息:{}", msgs);
			// 接着判断pageNum=0时

			for (ManualCustomer one : msgs) {
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("msgId", one.getId());
				map.put("srcId", one.getScrId());
				map.put("dstId", one.getDstId());
				map.put("msgTime", one.getSendTime());
				map.put("msg", one.getMsg());

				list.add(map);
			}
			// 接受成功后返回状态0,Arraylist数组
			maxmap.put("result", "0");
			maxmap.put("clientArray", list);

		} catch (Exception e) {
			e.printStackTrace();
			logger.error("serverGetHistoryMsg error:", e);
			maxmap.put("result", "1");
			maxmap.put("Errmsg", "失败");
		}
		// 转成JsontoString
		String json = JSON.toJSONString(maxmap, true);
		// 日志
		logger.info("serverGetHistoryMsg out json:{}", json);
		return json;
	}

	/**
	 * 客户端拉取历史消息
	 */
	@Override
	public String clientGetHistoryMsg(int userId, int pageNum, int pageSize) {
		// 日志
		logger.info("clientGetHistoryMsg in:userId{},pageNum{},pageSize{}", userId, pageNum, pageSize);
		Map<String, Object> maxmap = new HashMap<String, Object>();
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();

		try {
			int skip = (pageNum - 1) * pageSize;
			Map<String, Integer> params = new HashMap<String, Integer>();
			params.put("userId", userId);
			params.put("skip", skip);
			params.put("pageSize", pageSize);
			// 先客服 会根据自身的id和客户的id进行对数据库中查询，有则拉取回来
			ArrayList<ManualCustomer> msgs = manualcustomerDao.SelectClientMsg(params);

			// 日志
			logger.info("selectByDstId信息:{}", msgs);
			// 接着判断pageNum=0时

			for (ManualCustomer one : msgs) {
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("msgId", one.getId());
				map.put("srcId", one.getScrId());
				map.put("dstId", one.getDstId());
				map.put("msgTime", one.getSendTime());
				map.put("msg", one.getMsg());
				list.add(map);
			}
			// 接受成功后返回状态0,Arraylist数组
			maxmap.put("result", "0");
			maxmap.put("clientArray", list);

		} catch (Exception e) {
			e.printStackTrace();
			logger.error("clientGetHistoryMsg error:", e);
			maxmap.put("result", "1");
			maxmap.put("Errmsg", "失败");
		}
		// 转成JsontoString
		String json = JSON.toJSONString(maxmap, true);
		// 日志
		logger.info("clientGetHistoryMsg out json:{}", json);
		return json;
	}

	/**
	 * 客服端拉取历史消息
	 */
	@Override
	public String serverGetClientId(int serverId, int userId) {
		JSONObject jObject = new JSONObject();
		try {
			// 获取
			customerContext = CustomerContext.getInstance();
			// 客服获取客服ID
			int ret = customerContext.getClentId(serverId, userId);
			if (0 == ret) {
				jObject.put("result", "1");
				jObject.put("msg", "当前客户已经被分配，请拉取其他客户");
				return jObject.toJSONString();
			} else if (-1 == ret) {
				jObject.put("result", "2");
				jObject.put("msg", "您已经达到最大客服同时在线数，请先关闭已经服务完成的客户");
				return jObject.toJSONString();
			}

			jObject.put("result", "0");
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("serverGetClientId error:", e);
			jObject.put("result", "3");
			jObject.put("msg", "获取失败 ");
		}

		return jObject.toJSONString();

	}

	/**
	 * 客服登录
	 */
	@Override
	public String serverLogin(String userMark, String password, String deviceId) {
		JSONObject jObject = new JSONObject();

		try {
			// 判断账号是否为空
			if (userMark == null || userMark.trim().isEmpty()) {
				jObject.put("result", "1");
				jObject.put("msg", "帐户名不能为空");
				return jObject.toJSONString();
			}
			// 判断账号的长度
			if (userMark.length() > 14 || userMark.length() < 1) {
				jObject.put("result", "2");
				jObject.put("msg", "帐户名长度不对");
				return jObject.toJSONString();
			}
			// 判断密码
			if (password == null || password.trim().isEmpty()) {
				jObject.put("result", "4");
				jObject.put("msg", "密码不能为空");
				return jObject.toJSONString();
			}

			// 查询表中是否有这个账户
			CustomerServiceInformation selectByName = customerdao.selectByName(userMark);
			// 判断用户是否存在
			if (selectByName == null) {
				jObject.put("result", "3");
				jObject.put("msg", "用户不存在");
				return jObject.toJSONString();
			}

			// 判断客服是否被冻结
			if (selectByName.getState().equals("1")) {
				jObject.put("result", "3");
				jObject.put("msg", "用户已冻结");
				return jObject.toJSONString();
			}

			// 判断表 中密码和输入密码是否一致
			if (password.equals(selectByName.getPassword())) {
				// 登录成功
				// 返回用户信息
				// 生成一个token
				String tmpStr = userMark + "," + System.currentTimeMillis();
				String token = UtilsDto.crypt(tmpStr);

				// 把token存入jedisClient
				jedisClient.set(String.valueOf("customertoken" + selectByName.getId()), token);

				// 客服登录 建立客服服务记录
				CustomerContext customerContext = CustomerContext.getInstance();
				logger.debug("customer on hashcode:{}", customerContext.hashCode());
				customerContext.serverOnline(selectByName.getId(), selectByName.getMaximum());

				// 记录单点登陆信息
				LoaclauthServiceimpl.onlineMap.put(selectByName.getId(), (int) (System.currentTimeMillis() / 1000));
				LoaclauthServiceimpl.ssoMap.put(selectByName.getId(), deviceId);

				jObject.put("result", "0");
				jObject.put("userId", selectByName.getId());
				jObject.put("headPic", selectByName.getHeadPic());
				jObject.put("userName", selectByName.getServerName());
				jObject.put("nickName", selectByName.getNickName());
				jObject.put("token", token);
				jObject.put("msg", "登录成功");

			} else {
				jObject.put("result", "5");
				jObject.put("msg", "密码错误");
			}

		} catch (Exception e) {
			e.printStackTrace();
			logger.error("serverLogin error:", e);
			jObject.put("result", "6");
			jObject.put("msg", "登录失败");
		}
		return jObject.toJSONString();
	}

	/**
	 * 修改密码接口
	 */
	@Override
	public String serverModifyPasswd(Integer userId, String newPassword, String oldPassword) {
		JSONObject jObject = new JSONObject();
		try {
			// 根据userId查询出他的信息
			CustomerServiceInformation customer = customerdao.selectById(userId);
			// 判断有没有这个用户
			if (customer == null) {
				jObject.put("result", "2");
				jObject.put("msg", "没有这个用户");
				return jObject.toJSONString();
			}
			// 判断表中的密码和客服输入的旧密码是否一样
			if (!customer.getPassword().equals(oldPassword)) {
				logger.error("modify fail {}--{}", customer.getPassword(), oldPassword);
				jObject.put("result", "1");
				jObject.put("msg", "输入的原密码错误");
				return jObject.toJSONString();
			}
			CustomerServiceInformation ct = new CustomerServiceInformation();
			ct.setId(userId);
			ct.setPassword(newPassword);
			customerdao.updateByServer(ct);
			jObject.put("result", "0");
			jObject.put("msg", "修改密码成功");
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("serverModifyPasswd error:", e);
			jObject.put("result", "6");
			jObject.put("msg", "修改密码失败");
		}
		return jObject.toJSONString();
	}

	/**
	 * 客服修改个人信息
	 */
	@Override
	public String updatecustomerInfo(int serverId, String nickName, String phoneNum) {
		JSONObject jObject = new JSONObject();
		try {

			// 判断昵称最高不超过14个长度[a-zA-Z]{1,14}|[\u4e00-\u9fa5]{1,7}
			String str = "/^[\u4e00-\u9fa5a-zA-Z0-9_]+$/";
			if (nickName.matches(str)) {
				jObject.put("result", "2");
				jObject.put("msg", "请输入1~14个英文字母或者不超过7个中文汉字 ");
				return jObject.toJSONString();
			}

			// 判断手机号1开头，不能低于11位数
			if (phoneNum.startsWith("1") && phoneNum.length() == 11) {
				try {
					// 字符串转换成Long型的数字
					Long i = Long.parseLong(phoneNum);
					logger.info("phoneNum:{}", i);
				} catch (Exception e) {
					e.printStackTrace();
					jObject.put("result", "3");
					jObject.put("msg", "手机号不正确");
					return jObject.toJSONString();
				}
			} else {
				jObject.put("result", "4");
				jObject.put("msg", "手机号不正确");
				return jObject.toJSONString();
			}
			// 根据id查询出 这个客服
			CustomerServiceInformation selectById = customerdao.selectById(serverId);

			if (selectById == null) {
				jObject.put("result", "1");
				jObject.put("msg", "没有这个客服");
				return jObject.toJSONString();
			}

			// 修改信息后存入 表中
			CustomerServiceInformation csf = new CustomerServiceInformation();
			csf.setId(serverId);
			csf.setNickName(nickName);
			csf.setPhoneNum(phoneNum);
			customerdao.updataServer(csf);

			// 返回状态
			jObject.put("result", "0");
			jObject.put("msg", "修改成功");

		} catch (Exception e) {
			e.printStackTrace();
			logger.error("updatecustomerInfo error:", e);
			// 返回状态
			jObject.put("result", "5");
			jObject.put("msg", "修改失败");

		}
		return jObject.toJSONString();
	}

	/**
	 * 客服充值接口
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public String customerRecharge(int serverId, String token, int userId, int rechargeAmount, int rechargeDiamond,
			String orderId) throws Exception {
		JSONObject jObject = new JSONObject();
		Account account = new Account();
		try {
			// 客服验证
			String rToken = jedisClient.get(String.valueOf("customertoken" + serverId));
			if (!token.equals(rToken)) {
				jObject.put("result", "2");
				jObject.put("msg", "客服身份验证失败");
				return jObject.toJSONString();
			}

			AccountTransaction selectByorderId = accounttransactiondao.selectByorderId(orderId);
			if (selectByorderId != null) {
				jObject.put("result", "2");
				jObject.put("msg", "订单号已经充值！");
				return jObject.toJSONString();
			}

			// 先根据用户 id来查询出 account表中有没有这个用户
			Account userAccount = accountdao.selectAccountByUserId(userId);
			if (userAccount == null) {
				jObject.put("result", "3");
				jObject.put("msg", "没有这个客户");
				return jObject.toJSONString();
			}
			// 再根据userid对 account表进行插入彩钻数量
			// 先加上原先 的彩钻数量
			account.setUserId(userId);
			account.setAccountFunds(rechargeDiamond);
			int updateNum = accountdao.addAccount(account);
			logger.info("********updateNum*****{}", updateNum);
			if (updateNum == 0) {
				jObject.put("result", "4");
				jObject.put("msg", "充值异常");
				return jObject.toJSONString();
			}

			// 获取这个用户 的账号id
			int accountId = userAccount.getId();
			// 向这个表中插入充值金额 ，账户变动时间，账户变更类型 ，资金 来源 ，备注
			AccountTransaction accounttransaction = new AccountTransaction();
			accounttransaction.setOrderId(RandCodeUtil.getOrderId());
			accounttransaction.setAccountId(accountId);
			accounttransaction.setTransactionDate(new Date());
			accounttransaction.setTransactionMoney(rechargeDiamond);
			accounttransaction.setOrderId(orderId);
			accounttransaction.setMoney(rechargeAmount);
			accounttransaction.setTransactionType(1);
			accounttransaction.setMoneySources("客服充值");
			accounttransaction.setState(1);
			accounttransaction.setRemarks("充值客服：" + String.valueOf(serverId));
			accounttransaction.setOperator(serverId);
			accounttransaction.setFinishTime(DateUtil.getFormatDate("yyyy-MM-dd HH:mm:ss"));
			accounttransactiondao.insertAccountTransaction(accounttransaction);

			Notice notice = new Notice();
			notice.setNoticeDate(new Date());
			notice.setUserId(userId); // 管理员发布公告默认 user_id=0
			notice.setNoticeInfo("您好，您充值的" + rechargeAmount + "元已经到账！");
			notice.setBeread(0);
			noticeDao.insertNotice(notice);

			// 分成计算
			User user = userdao.selectId(userId);
			String agencyId = user.getAgencyId();
			if (agencyId != null && !agencyId.equals("")) {
				Agency agency = agencydao.selectAgency(agencyId);
				if (agency != null) {
					BettingLimitation betLimit = bettinglimitationDao.selectMaxMinBet();
					double rebateAmount = rechargeAmount * betLimit.getChannel();

					account.setUserId(agency.getUserId());
					account.setAccountFunds(rebateAmount);
					updateNum = accountdao.addAccount(account);
					logger.info("********updateNum*****{}", updateNum);
					if (updateNum > 0) {
						Account account1 = accountdao.selectAccountByUserId(agency.getUserId());
						AccountTransaction at = new AccountTransaction();
						at.setAccountId(account1.getId());
						at.setTransactionDate(new Date());
						at.setTransactionMoney(rebateAmount);
						at.setOrderId(RandCodeUtil.getOrderId());
						at.setMoney(rebateAmount);
						at.setTransactionType(9);
						at.setMoneySources("充值分成");
						at.setState(1);
						at.setRemarks("充值分成：" + String.valueOf(serverId));
						at.setFinishTime(DateUtil.getFormatDate("yyyy-MM-dd HH:mm:ss"));
						accounttransactiondao.insertAccountTransaction(at);
					}
				}
			}

			jObject.put("result", "0");
			jObject.put("msg", "充值成功");
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("customerRecharge error:", e);
			jObject.put("result", "1");
			jObject.put("msg", "充值失败");
			throw new Exception("充值失败");
		}
		return jObject.toJSONString();
	}

	/**
	 * 获取彩钻数量接口
	 */
	@Override
	public String getDiamondNum(int serverId, int rechargeAmount, int flag) {
		JSONObject jObject = new JSONObject();
		try {
			if (rechargeAmount > Integer.parseInt(LIMITAUTOCASH)) {
				jObject.put("result", "1");
				jObject.put("msg", "单次额度最大为" + LIMITAUTOCASH);
				return jObject.toJSONString();
			}
			jObject.put("result", "0");
			jObject.put("msg", "获取成功");
			jObject.put("rechargeDiamond", rechargeAmount);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("getDiamondNum error:", e);
			jObject.put("result", "1");
			jObject.put("msg", "获取失败");
		}
		return jObject.toJSONString();
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String customerCash(int serverId, String token, int userId, int withdrawcash, int withdrawDiamond)
			throws Exception {

		JSONObject jObject = new JSONObject();
		Account account = new Account();
		try {
			// 客服验证
			String rToken = jedisClient.get(String.valueOf("customertoken" + serverId));
			if (!token.equals(rToken)) {
				jObject.put("result", "2");
				jObject.put("msg", "客服身份验证失败");
				return jObject.toJSONString();
			}
			// 先根据用户 id来查询出 account表中有没有这个用户
			Account userAccount = accountdao.selectAccountByUserId(userId);
			if (userAccount == null) {
				jObject.put("result", "3");
				jObject.put("msg", "没有这个客户");
				return jObject.toJSONString();
			}

			if (userAccount.getAccountFunds() < withdrawDiamond) {
				jObject.put("result", "4");
				jObject.put("msg", "余额不足");
				return jObject.toJSONString();
			}
			account.setUserId(userId);
			account.setAccountFunds(withdrawDiamond);
			int updateNum = accountdao.reduceAccount(account);
			logger.info("********updateNum*****{}", updateNum);
			if (updateNum == 0) {
				jObject.put("result", "5");
				jObject.put("msg", "提现异常");
				return jObject.toJSONString();
			}

			// 获取这个用户 的账号id
			int accountId = userAccount.getId();
			// 向这个表中插入充值金额 ，账户变动时间，账户变更类型 ，资金 来源 ，备注
			AccountTransaction accounttransaction = new AccountTransaction();
			accounttransaction.setOrderId(RandCodeUtil.getOrderId());
			accounttransaction.setAccountId(accountId);
			accounttransaction.setTransactionDate(new Date());
			accounttransaction.setTransactionMoney(withdrawDiamond);
			accounttransaction.setMoney(withdrawcash);
			accounttransaction.setTransactionType(2);
			accounttransaction.setMoneyGo("客服提现");
			accounttransaction.setRemarks("客服提现ID：" + String.valueOf(serverId));
			accounttransaction.setOperator(serverId);
			accounttransaction.setState(1);
			accounttransaction.setFinishTime(DateUtil.getFormatDate("yyyy-MM-dd HH:mm:ss"));
			accounttransactiondao.insertAccountTransaction(accounttransaction);
			jObject.put("result", "0");
			jObject.put("msg", "提现成功");
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("customerCash error:", e);
			jObject.put("result", "1");
			jObject.put("msg", "提现失败");
			throw new Exception("提现失败");
		}
		return jObject.toJSONString();
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String autoCash(int userId, int cashType, int withdrawDiamond, String cashAccout, String cashName,
			int amount, String phoneNum, String code) throws Exception {
		// 先根据用户 id来查询出 account表中有没有这个用户
		JSONObject jObject = new JSONObject();
		try {

			if (amount > Integer.parseInt(LIMITAUTOCASH) || amount < 10) {
				jObject.put("result", "7");
				jObject.put("msg", "单次限额为10--" + LIMITAUTOCASH);
				return jObject.toJSONString();
			}

			String rCode = jedisClient.get(LOGINSYSTEM1 + phoneNum);
			if (!code.equals(rCode)) {
				jObject.put("result", "5");
				jObject.put("msg", "短信验证码错误");
				return jObject.toJSONString();
			}
			jedisClient.del(LOGINSYSTEM1 + phoneNum);

			if (1 == cashType && cashName.equals("")) {
				jObject.put("result", "2");
				jObject.put("msg", "银行卡转账，持卡人不能为空");
				return jObject.toJSONString();
			}

			Account userAccount = accountdao.selectAccountByUserId(userId);
			if (userAccount == null) {
				jObject.put("result", "2");
				jObject.put("msg", "没有这个客户");
				return jObject.toJSONString();
			}

			User user = userdao.selectId(userId);
			if (user.getState().equals("2")) {
				jObject.put("result", "2");
				jObject.put("msg", "不允许提现");
				return jObject.toJSONString();
			} else if (user.getState().equals("0")) {
				jObject.put("result", "2");
				jObject.put("msg", "此用户已被冻结");
				return jObject.toJSONString();
			}

			// 首次提现判断
			int cnt = accounttransactiondao.selectTransactionCountById(userAccount.getId());
			if (cnt == 0) {
				if (userAccount.getAccountFunds() < 288) {
					jObject.put("result", "3");
					jObject.put("msg", "首次提现余额要大于288");
					return jObject.toJSONString();
				}
				if (userAccount.getAccountFunds() - amount < 28) {
					jObject.put("result", "3");
					jObject.put("msg", "首次提现后余额要大于28");
					return jObject.toJSONString();
				}
				int sumAmunt = bettinginfoDao.selectUserbetAmount(userId);
				if (sumAmunt < 288) {
					jObject.put("result", "3");
					jObject.put("msg", "首次提现时下注总额要超过288");
					return jObject.toJSONString();
				}
			}

			if (userAccount.getAccountFunds() < withdrawDiamond) {
				jObject.put("result", "3");
				jObject.put("msg", "余额不足");
				return jObject.toJSONString();
			}

			if (accounttransactiondao.getCashTimes(userAccount.getId()) > Integer.parseInt(AUTOCASH)) {
				jObject.put("result", "6");
				jObject.put("msg", "超出提现次数");
				return jObject.toJSONString();
			}

			Account account = new Account();
			account.setUserId(userId);
			account.setAccountFunds(withdrawDiamond);
			int updateNum = accountdao.reduceAccount(account);
			logger.info("********updateNum*****{}", updateNum);
			if (updateNum == 0) {
				jObject.put("result", "4");
				jObject.put("msg", "提现异常");
				return jObject.toJSONString();
			}

			// 获取这个用户 的账号id
			int accountId = userAccount.getId();
			// 向这个表中插入充值金额 ，账户变动时间，账户变更类型 ，资金 来源 ，备注
			double commission = 0.0;
			if (amount > 100) {
				commission = amount * 0.02;
			} else {
				commission = 3;
			}
			AccountTransaction accounttransaction = new AccountTransaction();
			accounttransaction.setOrderId(RandCodeUtil.getOrderId());
			accounttransaction.setAccountId(accountId);
			accounttransaction.setTransactionDate(new Date());
			accounttransaction.setTransactionMoney(withdrawDiamond);
			accounttransaction.setMoney(amount);
			accounttransaction.setFee(commission);
			accounttransaction.setTransactionType(6);
			accounttransaction.setCashType(cashType);
			accounttransaction.setCashAccout(cashAccout);
			accounttransaction.setCashName(cashName);
			if (amount > 3000) {
				accounttransaction.setState(4);
			} else {
				accounttransaction.setState(0);
			}
			accounttransaction.setMoneyGo("自动提现");
			accounttransaction.setRemarks("自主提现");
			accounttransactiondao.insertAccountTransaction(accounttransaction);
			jObject.put("result", "0");
			jObject.put("msg", "提现成功");
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("autoCash error:", e);
			jObject.put("result", "1");
			jObject.put("msg", "提现失败,未知原因，请联系客服");
			throw new Exception("autoCash error");
		}
		return jObject.toJSONString();
	}

	/**
	 * 修改订单状态
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public String updateState(String orderId, int state, String remark) throws Exception {
		JSONObject jObject = new JSONObject();
		try {
			// if (null != HOSTADDR && !"".equals(HOSTADDR)) {
			//
			// if (!hostAddr.equals(HOSTADDR)) {
			// jObject.put("result", "2");
			// jObject.put("msg", "访问地址有误");
			// return jObject.toJSONString();
			// }
			// }
			AccountTransaction selectByorderId = accounttransactiondao.selectByorderId(orderId);
			if (selectByorderId == null) {
				jObject.put("result", "2");
				jObject.put("msg", "没有这个订单号！");
				return jObject.toJSONString();
			}
			if (selectByorderId.getState() == 1 || selectByorderId.getState() == 2) {
				jObject.put("result", "2");
				jObject.put("msg", "此订单已经更新为成功或者失败状态，不允许更改！");
				return jObject.toJSONString();
			}

			// 失败返还客户金额
			if (state == 2) {
				Account account = new Account();
				account.setId(selectByorderId.getAccountId());
				account.setAccountFunds(selectByorderId.getTransactionMoney());

				int updateNum = accountdao.addAccount(account);
				logger.info("********updateNum*****{}", updateNum);
				if (updateNum == 0) {
					jObject.put("result", "3");
					jObject.put("msg", "系统异常");
					return jObject.toJSONString();
				}
			}

			AccountTransaction ac = new AccountTransaction();
			ac.setState(state);
			ac.setId(selectByorderId.getId());
			ac.setRemarks(remark);
			// ac.setRealtransfermoney(aliRealTransfer);
			// ac.setAliFee(aliFee);
			// ac.setAotoTransferId(aotoTransferId);
			accounttransactiondao.updateAccountTransaction(ac);
			jObject.put("result", "0");
			jObject.put("msg", "修改成功");

		} catch (Exception e) {
			e.printStackTrace();
			logger.error("updateState error:", e);
			jObject.put("result", "1");
			jObject.put("msg", "修改失败");
			throw new Exception("regist error");
		}
		return jObject.toJSONString();
	}

	@Override
	public String getUnknowOrders(String hostAddr) {
		Map<String, Object> maxmap = new HashMap<String, Object>();
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		try {
			// if (null != HOSTADDR && !"".equals(HOSTADDR)) {
			//
			// if (!hostAddr.equals(HOSTADDR)) {
			// // maxmap.put("result", "2");
			// // maxmap.put("msg", "访问地址有误");
			// return JSON.toJSONString(list, true);
			// }
			// }

			List<AccountTransaction> tranList = accounttransactiondao.selectAccountTransactionBystate(3);
			for (AccountTransaction one : tranList) {
				AccountTransaction selectByorderId = accounttransactiondao.selectByorderId(one.getOrderId());
				Account ac = accountdao.selectAccountById(selectByorderId.getAccountId());
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("orderId", one.getOrderId());
				map.put("cashMoney", "" + (int) one.getTransactionMoney());
				map.put("userId", ac.getUserId());
				map.put("cashAccount", one.getCashAccout());
				map.put("cashName", one.getCashName());
				// map.put("alipay_account", one.getCashAccout());
				map.put("type", one.getCashType());

				// String userRealGetMoney = "";
				// if (one.getMoney() > 100.0) {
				// userRealGetMoney = "" + (int) (one.getMoney() * (1 - 0.02));
				// } else {
				// userRealGetMoney = "" + ((int) (one.getMoney()) - 3);
				// }
				// map.put("user_real_get_money", userRealGetMoney);
				// map.put("alipay_real_name", one.getCashName());
				list.add(map);
			}
			maxmap.put("array", list);
			maxmap.put("result", "0");
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("getUnknowOrders error:", e);
			maxmap.put("result", "1");
			maxmap.put("msg", "获取失败");
			return JSON.toJSONString(maxmap, true);
		}
		return JSON.toJSONString(maxmap, true);
	}

	@Override
	public String getOrders(String hostAddr) {
		Map<String, Object> maxmap = new HashMap<String, Object>();
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		try {
			// if (null != HOSTADDR && !"".equals(HOSTADDR)) {
			//
			// if (!hostAddr.equals(HOSTADDR)) {
			// // maxmap.put("result", "2");
			// // maxmap.put("msg", "访问地址有误");
			// return JSON.toJSONString(list, true);
			// }
			// }

			List<AccountTransaction> tranList = accounttransactiondao.selectAccountTransactionBystate(0);
			for (AccountTransaction one : tranList) {
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("id", one.getOrderId());
				map.put("cash_money", "" + (int) one.getMoney());
				map.put("alipay_account", one.getCashAccout());
				// map.put("type", one.getCashType());

				String userRealGetMoney = "";
				if (one.getMoney() > 100.0) {
					userRealGetMoney = "" + (int) (one.getMoney() * (1 - 0.02));
				} else {
					userRealGetMoney = "" + ((int) (one.getMoney()) - 3);
				}
				map.put("user_real_get_money", userRealGetMoney);
				map.put("alipay_real_name", one.getCashName());
				list.add(map);
			}
			// maxmap.put("array", list);
			// maxmap.put("result", "0");
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("getOrders error:", e);
			// maxmap.put("result", "1");
			// maxmap.put("msg", "获取失败");
			// return JSON.toJSONString(list, true);
		}
		return JSON.toJSONString(list, true);
	}

	@Override
	public String clientgetcash(int userId, int withdrawDiamond) {
		JSONObject jObject = new JSONObject();
		try {
			if (withdrawDiamond > 1000000) {
				jObject.put("result", "1");
				jObject.put("msg", "单次最大额度为1000000");
				return jObject.toJSONString();
			}
			jObject.put("result", "0");
			jObject.put("msg", "获取成功");
			jObject.put("withdrawDiamond", withdrawDiamond);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("clientgetcash error:", e);
			jObject.put("result", "2");
			jObject.put("msg", "获取失败");
		}
		return jObject.toJSONString();
	}

	/**
	 * 返点操作
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void RebateService() throws Exception {
		logger.debug("go to RebateService......");
		String key = DateUtil.getFormatDate("yyyyMMdd");
		if (jedisClient.incr(key) != 1) {
			logger.debug("go to RebateService again, will return......");
			return;
		}
		jedisClient.expire(key, 10 * 60);

		int pageNow = 1;
		try {
			BettingLimitation betLimit = bettinglimitationDao.selectMaxMinBet();
			double a = betLimit.getRebate(); // 用户返点
			double platformDivision = betLimit.getPlatformDivision(); // 平台返点
			while (true) {
				int startCount = (pageNow - 1) * 50;
				List<Rebate> queryRebate = accounttransactionDao.queryRebate(startCount);
				if (null == queryRebate || queryRebate.size() == 0) {
					break;
				}
				for (Rebate rebate : queryRebate) {
					logger.debug("rebate: {} -- {}", a, rebate.getMoney());
					int money = (int) (rebate.getMoney() * a);
					if (money == 0) {
						logger.info("rebate is zero");
						continue;
					}
					int userId = rebate.getUserId();
					// 添加金额
					Account account = new Account();
					account.setUserId(userId);
					account.setAccountFunds(money);
					accountdao.addAccount(account);
					// 中奖金额账户流水
					AccountTransactionDto accountTransactionDto = new AccountTransactionDto();
					accountTransactionDto.setUserId(userId);
					accountTransactionDto.setOrderId(RandCodeUtil.getOrderId());
					accountTransactionDto.setMoneySources("用户返点金额");
					accountTransactionDto.setTransactionMoney(money);
					accountTransactionDto.setTransactionType(7);
					accountTransactionDto.setState(1);
					withdrawalsService.insertAccountTransactionDto(accountTransactionDto);

					// 平台返点金额
					User user = userdao.selectId(userId);
					String agencyId = user.getAgencyId();
					if (agencyId == null || agencyId.equals("")) {
						continue;
					}
					Agency agency = agencydao.selectAgency(agencyId);
					if (agency == null) {
						continue;
					}
					Account account1 = accountdao.selectAccountByUserId(agency.getUserId());
					double platformDivisionMoney = rebate.getMoney() * platformDivision;

					AccountTransaction accounttransaction = new AccountTransaction();
					accounttransaction.setAccountId(account1.getId());
					accounttransaction.setTransactionMoney(platformDivisionMoney);
					accounttransaction.setTransactionType(8);
					accounttransaction.setTransactionDate(new Date());
					accounttransaction.setMoneySources("平台返点金额");
					accounttransaction.setState(1);
					accounttransaction.setOrderId(RandCodeUtil.getOrderId());
					accounttransactionDao.insertAccountTransaction(accounttransaction);

					account.setUserId(account1.getUserId());
					account.setAccountFunds(platformDivisionMoney);
					accountdao.addAccount(account);
				}

				pageNow++;
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("RebateService error", e);
			throw new Exception("平台返点失败");
		}
	}

	// 心跳包
	@Override
	public String heartbeat(int serverId, String deviceId) {
		JSONObject jObject = new JSONObject();
		// 覆盖用户的时间戳
		onlineMap.put(serverId, (int) (System.currentTimeMillis() / 1000));
		String did = LoaclauthServiceimpl.ssoMap.get(serverId);
		if (did != null && !deviceId.equals(did)) {
			logger.info("{}--{}", deviceId, did);
			jObject.put("result", "1");
			jObject.put("msg", "用户在其他地方登录，强行退出登录");
		} else {
			jObject.put("result", "0");
			jObject.put("msg", "成功");
		}

		return jObject.toString();
	}
}
